package com.qingcloud.adminbackend.controller.open;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.qingcloud.adminbackend.anno.CloudApi;
import com.qingcloud.adminbackend.anno.OpenApi;
import com.qingcloud.adminbackend.base.AjaxResult;
import com.qingcloud.adminbackend.base.ApiTreeNode;
import com.qingcloud.adminbackend.base.LoginRequest;
import com.qingcloud.adminbackend.controller.open.param.ChangePwdParam;
import com.qingcloud.adminbackend.controller.open.param.GridUserParam;
import com.qingcloud.adminbackend.controller.open.param.OrgInfoParam;
import com.qingcloud.adminbackend.entity.equipment.EquipmentProjectInfoDTO;
import com.qingcloud.adminbackend.entity.equipment.ModelDTO;
import com.qingcloud.adminbackend.entity.message.EventMessageInfoVO;
import com.qingcloud.adminbackend.entity.message.SysMessageEventSaveRule;
import com.qingcloud.adminbackend.entity.message.SysMessageTypeField;
import com.qingcloud.adminbackend.entity.source.DataSource;
import com.qingcloud.adminbackend.entity.source.DataSourceDatabase;
import com.qingcloud.adminbackend.entity.source.DataSourceDatabaseDto;
import com.qingcloud.adminbackend.entity.sysfunction.FunctionRequest;
import com.qingcloud.adminbackend.entity.sysfunction.SysFunction;
import com.qingcloud.adminbackend.entity.sysorder.SysBusinessApp;
import com.qingcloud.adminbackend.entity.sysorder.SysOrderDTO;
import com.qingcloud.adminbackend.entity.sysorder.SysUserOrderMgrDTO;
import com.qingcloud.adminbackend.entity.sysorder.SysUserOrderRequest;
import com.qingcloud.adminbackend.entity.sysorg.SysBusinessTypeDTO;
import com.qingcloud.adminbackend.entity.sysorg.SysOrg;
import com.qingcloud.adminbackend.entity.sysorg.SysOrgInfo;
import com.qingcloud.adminbackend.entity.sysstation.StationProjectInfoDTO;
import com.qingcloud.adminbackend.entity.sysstation.*;
import com.qingcloud.adminbackend.entity.user.GridUserDTO;
import com.qingcloud.adminbackend.entity.user.SimpleUserDTO;
import com.qingcloud.adminbackend.entity.user.SysUser;
import com.qingcloud.adminbackend.entity.user.UserFlagDTO;
import com.qingcloud.adminbackend.entity.userdomain.UserDomainDTO;
import com.qingcloud.adminbackend.pojo.vo.sysproduct.ProductListVO;
import com.qingcloud.adminbackend.service.*;
import com.qingcloud.adminbackend.service.impl.BaseServiceImpl;
import com.qingcloud.adminbackend.service.impl.ISysProductCommandClassifyService;
import com.qingcloud.adminbackend.utils.DbColumnInfo;
import com.qingcloud.adminbackend.utils.DtoUtils;
import com.qingcloud.base.annotation.LoginUser;
import com.qingcloud.base.constant.SystemConstant;
import com.qingcloud.base.remote.pojo.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 权限平台对外API
 *
 * @author wangjinnan
 */
@RestController
@RequestMapping("/api")
public class AdminApiController {

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysFunctionService sysFunctionService;
    @Resource
    private IDataSourceService dataSourceService;

    @Resource
    private IDatabaseService dataSourceDatabaseService;

    @Resource
    private ISysOrderService sysOrderService;

    @Resource
    private BaseServiceImpl baseService;

    @Resource
    private ISysStationService sysStationService;

    @Resource
    private ISysOrgService sysOrgService;

    @Resource
    private ISysEquipmentService sysEquipmentService;

    @Resource
    private ISysProductTypeService sysProductTypeService;

    @Resource
    private ISysProductCommandClassifyService productCommandClassifyService;

    @Resource
    private ISysMessageService iSysMessageService;

    @Resource
    private IAppService appService;

    private static final TimedCache<String, LoginUserDTO> USER_CACHE = CacheUtil.newTimedCache(600000L);

    @OpenApi
    @ApiOperation(value = "修改用户密码接口", notes = "修改用户密码接口")
    @PutMapping(value = "/user/pwd/change")
    public AjaxResult changePassword(@RequestBody ChangePwdParam param) {
        return sysUserService.changePassword(param);
    }

    @OpenApi
    @ApiOperation(value = "账号禁用接口", notes = "账号禁用接口")
    @PutMapping(value = "/user/userForbidden/{userId}")
    public AjaxResult userForbidden(@PathVariable("userId") String userId) {
        sysUserService.updateLoginStatus(userId, String.valueOf(SystemConstant.COMMON_ACCOUINT_FORBIDDEN));
        return AjaxResult.success();
    }

    @OpenApi
    @ApiOperation(value = "查询客户下的用户信息", notes = "查询客户下的用户信息")
    @GetMapping(value = "/user/org/{orgId}")
    public List<SimpleUserDTO> findByIdList(@PathVariable("orgId") String orgId) {
        return sysUserService.findByOrgId(orgId);
    }

    @OpenApi
    @ApiOperation(value = "查询用户身份信息", notes = "查询用户身份信息")
    @GetMapping(value = "/user/flag/{userId}")
    public UserFlagDTO findUserFlag(@PathVariable("userId") String userId) {
        return sysUserService.findUserFlag(userId);
    }

    @OpenApi
    @ApiOperation(value = "按用户ID列表批量查询用户信息", notes = "按用户ID列表批量查询用户信息")
    @PostMapping(value = "/user/ids")
    public List<SimpleUserDTO> findByIdList(@RequestBody Collection<String> idList) {
        return sysUserService.findByIdList(idList);
    }

    @OpenApi
    @ApiOperation(value = "按账号列表批量查询用户信息", notes = "按账号列表批量查询用户信息")
    @PostMapping(value = "/user/names")
    public List<SimpleUserDTO> findByUsernameList(@RequestBody Collection<String> userNameList) {
        return sysUserService.findUsernameList(userNameList);
    }

    @OpenApi
    @ApiOperation(value = "按照登录名和姓名模糊查询所有用户", notes = "按照登录名和姓名模糊查询所有用户")
    @GetMapping(value = "/user/like/{name}")
    public List<SimpleUserDTO> findUserLike(@PathVariable("name") String name) {
        return sysUserService.findUserLike("%" + name + "%");
    }

    @OpenApi
    @ApiOperation(value = "查询网格员用户", notes = "查询网格员用户")
    @PostMapping(value = "/grid/user")
    public List<GridUserDTO> findGridUser(@RequestBody GridUserParam gridUserParam) {
        return sysUserService.findGridUser(gridUserParam);
    }

    @OpenApi
    @ApiOperation(value = "所有平台用户登录接口(旧)", notes = "所有平台用户登录接口(旧)")
    @PostMapping("/loginAllPlatforms")
    public LoginUserDTO loginAllPlatforms(@RequestBody LoginRequest loginRequest) {
        LoginUserDTO loginUserDTO = sysUserService.loginAllPlatforms(loginRequest);
        return loginUserDTO;
    }


    @OpenApi
    @ApiOperation(value = "查询用户分配的区域信息(All Platform)", notes = "查询用户分配的区域信息(All Platform)")
    @GetMapping(value = "/getUserDomains/{userId}")
    public AjaxResult findUserDomain(@PathVariable("userId") String userId) {
        return AjaxResult.ok(sysUserService.selectUserDomainList(userId));
    }

    @CloudApi
    @ApiOperation(value = "登录状态修改", notes = "登录状态修改")
    @PostMapping("/loginstatus/{userId}")
    public AjaxResult loginStatus(@PathVariable("userId") String userId) {
        //用户退出修改状态
        if (StrUtil.isNotBlank(userId)) {
            sysUserService.updateLoginInfoById(userId);
        }
        return AjaxResult.success();
    }

    @CloudApi
    @ApiOperation(value = "退出登录(All Platform)", notes = "退出登录(All Platform)")
    @PostMapping("/logout")
    public AjaxResult logout(HttpServletRequest request, HttpServletResponse response, @LoginUser LoginUserDTO loginUserDTO) {
        //用户退出修改状态
        if (loginUserDTO != null && StrUtil.isNotBlank(loginUserDTO.getUserId())) {
            sysUserService.loguot(loginUserDTO.getUserId());
        }
        return AjaxResult.success();
    }
    ///////////////////////////////////////end////////////////////////////////////////////

    @OpenApi
    @ApiOperation(value = "根据用户名获取用户信息", notes = "根据用户名获取用户信息")
    @GetMapping(value = "/findUser/{userName}")
    public LoginUserDTO getUserByName(@PathVariable("userName") String userName) {
        LoginUserDTO loginUserDTO = sysUserService.getUserByName(userName);
        return loginUserDTO;
    }

    @ApiOperation(value = "根据用户名获取用户信息", notes = "根据用户名获取用户信息")
    @GetMapping(value = "/findUserByUserId/{userId}")
    public LoginUserDTO findUserByUserId(@PathVariable("userId") String userId) {
        LoginUserDTO tempUser = USER_CACHE.get(userId, false);
        if (tempUser != null) {
            return tempUser;
        }
        LoginUserDTO loginUserDTO = sysUserService.getUserByUserId(userId);
        USER_CACHE.put(userId, loginUserDTO);
        return loginUserDTO;
    }

    @Deprecated
    @OpenApi
    @ApiOperation(value = "根据用户名获取用户信息", notes = "根据用户名获取用户信息")
    @PostMapping("/findUserById")
    public LoginUserDTO findUserById(@RequestParam("userId") String userId) {
        LoginUserDTO tempUser = USER_CACHE.get(userId, false);
        if (tempUser != null) {
            return tempUser;
        }
        LoginUserDTO loginUserDTO = sysUserService.getUserByUserId(userId);
        USER_CACHE.put(userId, loginUserDTO);
        return loginUserDTO;
    }


    ///////////////////////功能API begin
    @OpenApi
    @ApiOperation(value = "登陆用户所有权限编码", notes = "登陆用户所有权限编码")
//    @Cacheable(value = "func", key ="#functionRequest.userId+'-'+#functionRequest.menuType")
    @PostMapping("/function/code")
    public List<String> getAllFunctionCode(@RequestBody FunctionRequest functionRequest) {
        return sysFunctionService.getAllFunctionCode(functionRequest.getMenuType(), functionRequest.getUserId());
    }

    @OpenApi
    @ApiOperation(value = "登陆用户所有功能列表记录", notes = "登陆用户所有功能列表记录")
    @PostMapping("/function/list")
//    @Cacheable(value = "allfunc", key ="#functionRequest.userId+'-'+#functionRequest.menuType")
    public List<FunctionDTO> getAllFunctionList(@RequestBody FunctionRequest functionRequest) {
        List<SysFunction> functions = sysFunctionService.getAllFunction(functionRequest.getMenuType(), functionRequest.getUserId(), true);
        if (functions != null) {
            List<FunctionDTO> functionDTOS = new ArrayList<>();
            functions.forEach(f -> {
                functionDTOS.add(DtoUtils.entity2FunctionDto(f));
            });
            return functionDTOS;
        }
        return null;
    }

    @Deprecated
    @OpenApi
    @ApiOperation(value = "登录用户所有的菜单权限(All Platform)", notes = "登录用户所有的菜单权限(All Platform)")
    @PostMapping("/getFuncByUserId")
    public AjaxResult getFuncByUserId(@RequestBody FunctionRequest functionRequest) {
        Map<String, Object> map = sysFunctionService.getFunctionByUserId(functionRequest.getMenuType(), functionRequest.getUrlFlag(), functionRequest.getUserId());
        return AjaxResult.ok(map);
    }

    @OpenApi
    @ApiOperation(value = "登录用户所有的菜单权限", notes = "登录用户所有的菜单权限")
    @PostMapping("/getFunctionByUserId")
    public Map<String, Object> getFunctionByUserId(@RequestBody FunctionRequest functionRequest) {
        String userId = functionRequest.getUserId();
        return sysFunctionService.getFunctionByUserId(functionRequest.getMenuType(), functionRequest.getUrlFlag(), userId);
    }

    @Deprecated
    @OpenApi
    @ApiOperation(value = "根据用户以及业务类别获菜单树", notes = "根据用户以及业务类别获菜单树")
    @GetMapping(value = "/getMenuByUserAndType/{userId}/{menuType}")
    public List<MenuDTO> getMenuByUserAndType(@PathVariable("userId") String userId,
                                              @PathVariable("menuType") Integer menuType) {
        List<MenuDTO> menuDTOS = sysFunctionService.getMenuTree(userId, menuType);
        return menuDTOS;
    }


    @OpenApi
    @ApiOperation(value = "获取用户业务种类下有权限的订单", notes = "获取用户业务种类下有权限的订单", response = SysUserOrderMgrDTO.class)
    @PostMapping("/findOrdersByBusinessType")
    public List<SysOrderDTO> findOrdersByBusinessType(@RequestBody OrderParam orderParam, HttpServletRequest request) {
        boolean isAdmin = false;
        SysUser user = sysUserService.getById(orderParam.getUserId());
        if (user.getAdminFlag() == 1) {
            isAdmin = true;
        }

        List<SysOrderDTO> orderList = new ArrayList<>();
        SysUserOrderRequest orderRequest = new SysUserOrderRequest();
        orderRequest.setUserId(orderParam.getUserId());
        orderRequest.setBusinessTypes(Arrays.asList(orderParam.getBusinessTypes()));

        Set<SysUserOrderMgrDTO> orderSet = sysOrderService.getOrdersByBusinessType(orderRequest, isAdmin);
        for (SysUserOrderMgrDTO orderMgrDTO : orderSet) {
            SysOrderDTO orderDTO = new SysOrderDTO();
            orderDTO.setOrderId(orderMgrDTO.getId());
            orderDTO.setOrderName(orderMgrDTO.getOrderName());
            orderDTO.setOrgName(orderMgrDTO.getOrgName());
            orderDTO.setCreateTime(orderMgrDTO.getCreateTime());
            orderDTO.setDescribe(orderMgrDTO.getDescribe());
            orderDTO.setEquipmentNum(Integer.parseInt(orderMgrDTO.getEquipmentNum()));
            orderList.add(orderDTO);
        }

        return orderList;
    }

    @OpenApi
    @ApiOperation(value = "获取所有数据源", notes = "获取所有数据源", response = DataSource.class)
    @GetMapping("/getAllDatasource")
    public List<DataSource> getAllDatasource() {
        return dataSourceService.findAll();
    }

    @OpenApi
    @ApiOperation(value = "获取所有数据源数据库", notes = "获取所有数据源数据库", response = DataSource.class)
    @GetMapping("/findAllDsDb")
    public List<DataSourceDatabaseDto> findAllDsDb() {
        return dataSourceService.findAllDsDb();
    }

    @OpenApi
    @ApiOperation(value = "获取指定数据源下所有数据库", notes = "获取指定数据源下所有数据库", response = String.class)
    @GetMapping("/getAllCatalogByDataSourceId")
    public List<String> getAllCatalogByDataSourceId(@RequestParam("dataSourceId") Integer dataSourceId) {
        return dataSourceDatabaseService.getAllCatalogByDataSourceId(dataSourceId);
    }

    @OpenApi
    @ApiOperation(value = "获取数据库详情", notes = "获取数据库详情id", response = String.class)
    @GetMapping("/getDatabaseByDsId/{dsId}")
    public DataSourceDatabase getDatabaseByDsId(@PathVariable("dsId") Integer dsId) {
        return dataSourceDatabaseService.getDatabaseByDsId(dsId);
    }

    @OpenApi
    @ApiOperation(value = "批量获取数据库详情", notes = "批量获取数据库详情", response = String.class)
    @GetMapping("/getDatabaseByDsIds")
    public List<DataSourceDatabase> getDatabaseByDsId(@RequestParam("dsIds") String dsIds) {
        return dataSourceDatabaseService.getDatabaseByDsIds(dsIds);
    }

    @OpenApi
    @ApiOperation(value = "获取数据库详情", notes = "获取数据库详情name", response = String.class)
    @GetMapping("/getDatabaseByDsName")
    public DataSourceDatabase getDatabaseByDsName(@RequestParam("dsName") String dsName) {
        return dataSourceDatabaseService.getDatabaseByDsName(dsName);
    }

    @OpenApi
    @ApiOperation(value = "获取指定数据库下的所有表和字段名称", notes = "获取指定数据库下的所有表和字段名称", response = String.class)
    @GetMapping("/getTableAndColumnByCatalog")
    public List<DbColumnInfo> getTableAndColumn(@RequestParam("dataSourceId") Integer dataSourceId, @RequestParam("catalog") String catalog) {
        return dataSourceDatabaseService.getTableAndColumn(dataSourceId, catalog);
    }

    @OpenApi
    @ApiOperation(value = "获取用户可读的监测点编号", notes = "获取用户可读的监测点编号")
    @GetMapping(value = "/station/ids")
    public Set<String> getStationDataPermissions(@RequestParam("userId") String userId,
                                                 @RequestParam("workType") String workType) {
        //原蛙鸣用户的监测点权限
        List<ModelDTO> wamingStationList = baseService.getStationIds(userId, null, null, workType, 1, false);

        //原普通用户的监测点权限
        Set<ModelDTO> stationList = baseService.getUserStationIds(userId, workType);

        //合并起来返回
        stationList.addAll(wamingStationList);
        return stationList.stream().filter(it -> StrUtil.isNotBlank(it.getModelId()))
                .map(ModelDTO::getModelId).collect(Collectors.toSet());
    }

    @OpenApi
    @ApiOperation(value = "项目下监测点信息", notes = "项目下监测点信息")
    @GetMapping(value = "/project/station")
    public List<StationProjectInfoDTO> findOrderStation(@RequestParam String projectId,
                                                        @RequestParam Integer businessType) {
        return sysStationService.findByOrder(projectId, businessType);
    }

    @OpenApi
    @ApiOperation(value = "项目下设备编号", notes = "项目下设备编号")
    @GetMapping(value = "/project/equipment")
    public List<EquipmentProjectInfoDTO> findOrderEquipmentId(@RequestParam String projectId) {
        return sysEquipmentService.findByOrder(projectId);
    }

    @OpenApi
    @ApiOperation(value = "根据设备编号查询设备信息", notes = "根据设备编号查询设备信息")
    @PostMapping(value = "/equipment/info")
    public List<EquipmentProjectInfoDTO> findEquipmentInfo(@RequestBody List<String> equipmentIds) {
        return sysEquipmentService.findEquipmentOrderInfo(equipmentIds);
    }

    @OpenApi
    @ApiOperation(value = "批量查询客户信息", notes = "批量查询客户信息")
    @PostMapping(value = "/org")
    public List<SysOrgInfo> customerInfo(@RequestBody OrgInfoParam orgInfoParam) {
        return sysOrgService.findOrgInfo(orgInfoParam);
    }

    @OpenApi
    @ApiOperation(value = "根据客户ID查询客户信息", notes = "根据客户ID查询客户信息")
    @PostMapping(value = "/orginfo/{orgId}")
    public AjaxResult<SysOrg> findOrgInfo(@PathVariable("orgId") String orgId) {
        SysOrg sysOrg = sysOrgService.getById(orgId);
        return AjaxResult.ok(sysOrg);
    }

    @OpenApi
    @ApiOperation(value = "查询子客户信息", notes = "根据客户ID查询客户信息")
    @GetMapping(value = "/org/child/{parentId}")
    public List<SysOrgInfo> customerInfo(@PathVariable("parentId") String parentId) {
        return sysOrgService.findChild(parentId);
    }

    @OpenApi
    @ApiOperation(value = "查询用户任务管理权限的所有组织ID", notes = "查询用户任务管理权限的所有组织ID")
    @GetMapping(value = "/taskorg/ids")
    public Set<String> findUserTaskOrgIds(@RequestParam("userId") String userId) {
        return sysOrgService.findReadableUserTaskOrgIds(userId);
    }

    @OpenApi
    @ApiOperation(value = "查询用户任务所属组织", notes = "查询用户任务所属组织")
    @GetMapping(value = "/user/taskorg")
    public String findUserTaskOrg(@RequestParam("userId") String userId) {
        return sysOrgService.findUserTaskOrg(userId);
    }

    @OpenApi
    @ApiOperation(value = "监测点项目信息查询", notes = "监测点项目信息查询")
    @PostMapping(value = "/station/order")
    public List<StationProjectInfoDTO> findStationOrder(@RequestBody Set<String> sidSet) {
        return sysStationService.findStationOrder(sidSet);
    }

    @OpenApi
    @ApiOperation(value = "获取用户可读的设备编号", notes = "获取用户可读的设备编号")
    @GetMapping(value = "/equipment/ids")
    public Set<String> findReadableEquipment(@RequestParam String userId, @RequestParam Integer businessType) {
        //用户有权限的设备编号
        final Set<String> eidSet = baseService.getEquipmentIds(userId, null, null, 0)
                .stream().map(ModelDTO::getModelId).collect(Collectors.toSet());
        //筛选业务种类
        return sysEquipmentService.filterBusinessType(eidSet, businessType);
    }

//    @OpenApi
//    @ApiOperation(value = "气溶胶事件消息接入", notes = "气溶胶事件消息接入")
//    @PostMapping(value = "/event/message")
//    public AjaxResult findStationOrder(@RequestBody TdWcenterAppMessage tdWcenterAppMessage) {
//        int ad = wcenterAppMessageService.saveWcenterAppMessage(tdWcenterAppMessage);
//        if (ad != 1) {
//            return new AjaxResult(WamingConstant.FAILURE, "消息写入失败！", "");
//        }
//        return new AjaxResult(WamingConstant.SUCCESS, "消息写入成功！", "");
//    }

    @OpenApi
    @ApiOperation(value = "查询用户分配的区域信息", notes = "查询用户分配的区域信息")
    @GetMapping(value = "/user/domains/{userId}")
    public List<UserDomainDTO> findUserDomains(@PathVariable("userId") String userId) {
        return sysUserService.findUserDomain(userId);
    }

    @OpenApi
    @ApiOperation(value = "网格化需要同步的数据", notes = "网格化需要同步的数据")
    @GetMapping(value = "/sync/grid")
    public GridSyncDTO findStationSyncInfo(@RequestParam Integer businessType) {
        final GridSyncDTO dto = new GridSyncDTO();
        //监测点同步信息
        List<StationSyncDTO> stationList = sysStationService.findStationSyncInfo(businessType);
        dto.setStationList(stationList);
        if (CollUtil.isNotEmpty(stationList)) {
            //监测点绑定设备数据
            Set<String> stationIdSet = stationList.stream().map(StationSyncDTO::getStationId).collect(Collectors.toSet());
            List<StationBindDTO> bindList = sysStationService.findStationBindSync(stationIdSet);
            dto.setBindList(bindList);
        }
        //同步的设备信息
        List<EquipmentSyncDTO> equipmentList = sysEquipmentService.findEquipmentSyncInfo(businessType);
        dto.setEquipmentList(equipmentList);
        return dto;
    }

    @OpenApi
    @ApiOperation(value = "所有产品模型列表")
    @GetMapping("/selectAllProductList")
    public List<ProductListVO> selectAllProductList() {
        return sysProductTypeService.selectAllProductList();
    }

    @OpenApi
    @ApiOperation(value = "根据产品类型查询设备id列表")
    @GetMapping("/equipmentByProductType/{productType}")
    public List<String> selectAllProductList(@PathVariable("productType") String productType) {
        return sysEquipmentService.equipmentByProductType(productType);
    }

    @OpenApi
    @ApiOperation(value = "根据产品类型id查询指令模型菜单")
    @GetMapping("/productCommandClassifyTree/{productTypeId}")
    public List<ApiTreeNode> selectAllProductList(@PathVariable("productTypeId") Integer productTypeId) {
        return productCommandClassifyService.productCommandClassifyTree(productTypeId);
    }

    @OpenApi
    @ApiOperation(value = "事件通知配置查询", response = EventMessageInfoVO.class)
    @GetMapping("/eventNoticeConfigList")
    public List<EventMessageInfoVO> eventNoticeConfigList() {
        return iSysMessageService.eventNoticeConfigList();
    }

    @OpenApi
    @ApiOperation(value = "事件类型字段配置", response = SysMessageTypeField.class)
    @GetMapping("/event/fields/{typeId}")
    public List<SysMessageTypeField> findEventTypeField(@PathVariable("typeId") Integer typeId) {
        return iSysMessageService.findTypeFields(typeId);
    }

    @OpenApi
    @ApiOperation(value = "根据事件编码查询事件规则", response = SysMessageEventSaveRule.class)
    @GetMapping("/event/rules/{eventCode}")
    public SysMessageEventSaveRule findEventRules(@PathVariable("eventCode") String eventCode) {
        return iSysMessageService.findEventRuleDetail(eventCode);
    }

    @OpenApi
    @ApiOperation(value = "根据应用编号获取业务应用记录", notes = "根据应用编号获取业务应用记录")
    @GetMapping("/business/findByBizId/{origin}/{bizCode}")
    public com.qingcloud.base.pojo.AjaxResult findByBizId(@PathVariable("origin") Integer origin, @PathVariable("bizCode") String bizCode) {
        SysBusinessApp businessApp = sysOrderService.getSysBusinessAppByCode(origin, bizCode);
        if (businessApp != null)
            return com.qingcloud.base.pojo.AjaxResult.success(businessApp.getId());
        else
            return com.qingcloud.base.pojo.AjaxResult.fail("未找到对应的业务类型");
    }

    @OpenApi
    @ApiOperation(value = "应用拥有者信息查询", notes = "应用拥有者信息查询")
    @GetMapping(value = "/app/owner/{appId}")
    public SimpleUserDTO findAppOwner(@PathVariable("appId") Integer appId) {
        return appService.findAppOwner(appId);
    }

    @OpenApi
    @ApiOperation(value = "新增修改应用信息")
    @PostMapping(value = "/business/addOrUpdate")
    public com.qingcloud.base.pojo.AjaxResult registerBusinessApp(@RequestBody BusinessApp businessApp) {
        sysOrderService.registerApp(businessApp);
        return com.qingcloud.base.pojo.AjaxResult.success("业务应用操作成功");
    }

    @OpenApi
    @ApiOperation(value = "删除应用")
    @GetMapping("/business/{origin}/{bizCode}")
    public com.qingcloud.base.pojo.AjaxResult deleteBusinessApp(@PathVariable("origin") Integer origin, @PathVariable("bizCode") String bizCode) {
        sysOrderService.deleteBusinessApp(origin, bizCode);
        return com.qingcloud.base.pojo.AjaxResult.success("业务应用删除成功");
    }

    @OpenApi
    @ApiOperation(value = "应用权限过滤")
    @GetMapping("/business/filter/{userId}")
    public List<BusinessTypeDTO> businessAppFilter(@PathVariable("userId") String userId) {
        List<SysBusinessTypeDTO> data = sysOrgService.getBusinessType(userId);
        List<BusinessTypeDTO> targetList = new ArrayList<>();
        if (data != null) {
            for (int i = 0; i < data.size(); i++) {
                BusinessTypeDTO target = new BusinessTypeDTO();
                BeanUtil.copyProperties(data.get(i), target);
                targetList.add(target);
            }
        }
        return targetList;
    }

    @OpenApi
    @ApiOperation(value = "新增菜单功能", notes = "新增菜单功能")
    @PostMapping("/function/addFunction")
    public com.qingcloud.base.pojo.AjaxResult addFunction(@RequestBody FunctionDTO functionDTO) {
        SysFunction function = DtoUtils.functionDto2Entity(functionDTO);
        SysBusinessApp businessApp = sysOrderService.getSysBusinessAppByCode(functionDTO.getOrigin(), String.valueOf(functionDTO.getAppId()));
        if (businessApp != null) {
            function.setMenuType(businessApp.getId());
        }
        Map<String, SysFunction> result = sysFunctionService.addFunction(function);
        SysFunction sf = result.get("function");

        return com.qingcloud.base.pojo.AjaxResult.success(sf);
    }

    @OpenApi
    @ApiOperation(value = "修改菜单功能", notes = "修改菜单功能")
    @PostMapping("/function/updateFunction")
    public com.qingcloud.base.pojo.AjaxResult updateFunction(@RequestBody FunctionDTO functionDTO) {
        SysFunction function = DtoUtils.functionDto2Entity(functionDTO);
        if (StrUtil.isBlank(function.getId())) {
            function.setId(IdUtil.simpleUUID());
        }
        Map<String, SysFunction> result = sysFunctionService.updateFunction(function);
        SysFunction sf = result.get("function");
        return com.qingcloud.base.pojo.AjaxResult.success(sf);
    }

    @OpenApi
    @ApiOperation(value = "新增菜单功能", notes = "新增菜单功能")
    @PostMapping("/function/addOrUpdateFunction")
    public com.qingcloud.base.pojo.AjaxResult addOrUpdateFunction(@RequestBody FunctionDTO functionDTO) {
        SysFunction function = DtoUtils.functionDto2Entity(functionDTO);
        Integer appId = functionDTO.getAppId();
        Integer origin = functionDTO.getOrigin();
        SysBusinessApp businessApp = sysOrderService.getSysBusinessAppByCode(origin, String.valueOf(appId));
        if (businessApp != null) {
            function.setMenuType(businessApp.getId());
        }
        Map<String, SysFunction> result = null;
        if (StrUtil.isBlank(function.getId())) {
            result = sysFunctionService.addFunction(function);
        } else {
            SysFunction oldFunction = sysFunctionService.findById(function.getId());
            if (Objects.isNull(oldFunction)) {
                function.setId(IdUtil.simpleUUID());
                result = sysFunctionService.addFunction(function);
            } else {
                result = sysFunctionService.updateFunction(function);
            }
        }
        SysFunction sf = result.get("function");
        return com.qingcloud.base.pojo.AjaxResult.success(sf);
    }

    @OpenApi
    @ApiOperation(value = "删除功能权限", notes = "删除功能权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "functionIds", value = "功能ID字符串", dataType = "string", paramType = "path", required = true,
                    defaultValue = "40234481585db7d701585dc9f8a0001233"),
    })
    @PostMapping(value = "/delFunction/{functionIds}")
    public com.qingcloud.base.pojo.AjaxResult delFunction(@PathVariable("functionIds") String functionIds) {
        String[] listIds = functionIds.split(",");
        if (listIds != null && listIds.length > 0) {
            for (int i = 0; i < listIds.length; i++) {
                sysFunctionService.deleteFunction(listIds[i]);
            }
        }
        return com.qingcloud.base.pojo.AjaxResult.success("全部删除成功");

    }

    @OpenApi
    @ApiOperation(value = "查询子功能列表", notes = "查询子功能列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "functionIds", value = "功能ID字符串", dataType = "string", paramType = "path", required = true,
                    defaultValue = "40234481585db7d701585dc9f8a0001233"),
    })
    @GetMapping(value = "/function/child/{parentId}")
    public List<FunctionDTO> childFunction(@PathVariable("parentId") String parentId) {
        List<SysFunction> functions = sysFunctionService.findChild(parentId);
        return functions.stream().map(DtoUtils::entity2FunctionDto).toList();
    }

    @OpenApi
    @ApiOperation(value = "查询应用的权限编码", notes = "查询应用的权限编码")
    @PostMapping("/app/functions")
    public Map<String, Set<String>> getAppFunctionCode(@RequestBody AppFunctionParam param) {
        return appService.findAppFunctionCode(param);
    }

    @OpenApi
    @ApiOperation(value = "获取我参与的应用ID", notes = "获取我参与的应用ID")
    @PostMapping("/app/part/{userId}")
    public Set<Integer> getMyPartAppId(@PathVariable("userId") String userId) {
        return appService.getMyPartAppId(userId);
    }

}
